home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / viewers / mpgsrcpl.lha / org20 / mono.c < prev    next >
C/C++ Source or Header  |  2001-02-02  |  5KB  |  215 lines

  1. /*
  2.  * Author:    Yoichiro Ueno (ueno@cs.titech.ac.jp)
  3.  *
  4.  * Copyright (C) 1991, 1992, Yoichiro Ueno.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and
  7.  * its documentation for any purpose is hereby granted by the Author without
  8.  * fee, provided that the above copyright notice appear in all copies and
  9.  * that both the copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of the Author not be used
  11.  * in advertising or publicity pertaining to distribution of the software
  12.  * without specific, written prior permission.  The Author makes no
  13.  * representations about the suitability of this software for any purpose.
  14.  * It is provided "as is" without express or implied warranty.
  15.  *
  16.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  17.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  18.  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  19.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  20.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  21.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  22.  * PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  */
  25.  
  26. #include "video.h"
  27. #include "proto.h"
  28. #include "dither.h"
  29.  
  30.  
  31. /*
  32.  *--------------------------------------------------------------
  33.  *
  34.  * MonoDitherImage --
  35.  *
  36.  *    Dithers image into monochrome.
  37.  *    Dither algorithm is based on dither.c in xli.1.11.
  38.  *
  39.  * Results:
  40.  *    None.
  41.  *
  42.  * Side effects:
  43.  *    None.
  44.  *
  45.  *--------------------------------------------------------------
  46.  */
  47. #define MaxGrey        65280
  48. #define Threshold    (MaxGrey/2)
  49. #define MinGrey        0
  50.  
  51. #if ultrix && mips
  52. #    define SEED_BIT 0x01
  53. #    define OPP_SEED_BIT 0x80
  54. #    define SHIFT_SEED_BIT(b) (b <<= 1)
  55. #    define OPP_SHIFT_SEED_BIT(b) (b >>= 1)
  56. #else
  57. #    define SEED_BIT 0x80
  58. #    define OPP_SEED_BIT 0x01
  59. #    define SHIFT_SEED_BIT(b) (b >>= 1)
  60. #    define OPP_SHIFT_SEED_BIT(b) (b <<= 1)
  61. #endif
  62.  
  63. static int    *curr = NULL;
  64. static int    *next = NULL;
  65.  
  66. void
  67. MonoDitherImage(lum, cr, cb, out, h, w)
  68.     register unsigned char *lum;
  69.     unsigned char *cr;
  70.     unsigned char *cb;
  71.     register unsigned char *out;
  72.     int w, h;
  73. {
  74.   int bit_r2l;
  75.   register unsigned int bit;
  76.   register unsigned int data;
  77.   int i;
  78.   register int j;
  79.   int *swap;
  80.   register int out_err;
  81.   register int next1;
  82.   register int next2;
  83.  
  84.   if(curr == NULL) {
  85.     curr = (int *)malloc(sizeof(int) * (w + 2));
  86.     curr += 1;
  87.   }
  88.   if(next == NULL) {
  89.     next = (int *)malloc(sizeof(int) * (w + 2));
  90.     next += 1;
  91.   }
  92.  
  93.   bzero ((char *)curr, w * sizeof(*curr));
  94.  
  95.   bit_r2l = SEED_BIT << (w - 1 & 7);
  96.   for(i = 0; i < h; i ++) {
  97.     if(i & 0x01) {                /* Right to Left */
  98.       bit = bit_r2l;
  99.       data = 0;
  100.       out_err = curr[w-1];
  101.       next1 = 0;
  102.       next2 = 0;
  103.       for (j=(w-1); j>=0; j--)
  104.       {
  105.     out_err = (out_err >> 4) + (lum[j] << 8);
  106.     if(out_err > Threshold) {
  107.       data |= bit;
  108.       out_err -= MaxGrey;
  109.     }
  110.     else
  111.       out_err -= MinGrey;
  112.  
  113.     next[j+1] = next1 +     (out_err * 3);
  114.     next1     = next2 +     (out_err * 5);
  115.     next2     =             (out_err * 1);
  116.     out_err   = curr[j-1] + (out_err * 7);
  117.  
  118.     OPP_SHIFT_SEED_BIT(bit);
  119. #if ultrix && mips
  120.     if(bit == 0) {
  121. #else
  122.     if(bit > 0x80) {
  123. #endif
  124.       out[j >> 3] = data;
  125.       bit = OPP_SEED_BIT;
  126.       data = 0;
  127.     }
  128.       }
  129.       next[0] = next1;
  130.     }
  131.     else {                    /* Left to Right */
  132.       bit = SEED_BIT;
  133.       data = 0;
  134.       out_err = curr[0];
  135.       next1 = 0;
  136.       next2 = 0;
  137.       for (j=0; j<w; j++)
  138.       {
  139.     out_err = (out_err >> 4) + (lum[j] << 8);
  140.     if(out_err > Threshold) {
  141.       data |= bit;
  142.       out_err = out_err - MaxGrey;
  143.     }
  144.     else
  145.       out_err = out_err - MinGrey;
  146.  
  147.     next[j-1] = next1 +     (out_err * 3);
  148.     next1     = next2 +     (out_err * 5);
  149.     next2     =             (out_err * 1);
  150.     out_err   = curr[j+1] + (out_err * 7);
  151.  
  152.     SHIFT_SEED_BIT(bit);
  153. #if ultrix && mips
  154.     if(bit > 0x80) {
  155. #else
  156.     if(bit == 0) {
  157. #endif
  158.       out[j >> 3] = data;
  159.       bit = SEED_BIT;
  160.       data = 0;
  161.     }
  162.       }
  163.       next[w-1] = next1;
  164.     }
  165.     
  166.     lum += w;
  167.     out += w >> 3;
  168.     swap = curr;
  169.     curr = next;
  170.     next = swap;
  171.   }
  172. }
  173.  
  174.  
  175. /*
  176.  *--------------------------------------------------------------
  177.  *
  178.  * MonoThresholdImage --
  179.  *
  180.  *    convert image into monochrome with threshold.
  181.  *
  182.  * Results:
  183.  *    None.
  184.  *
  185.  * Side effects:
  186.  *    None.
  187.  *
  188.  *--------------------------------------------------------------
  189.  */
  190. void
  191. MonoThresholdImage(lum, cr, cb, out, h, w)
  192.     unsigned char *lum;
  193.     unsigned char *cr;
  194.     unsigned char *cb;
  195.     unsigned char *out;
  196.     int w, h;
  197. {
  198.   unsigned char    bit;
  199.   unsigned char    data;
  200.  
  201.   bit = SEED_BIT;
  202.   data = 0;
  203.   for (w*=h; w>0; w--) {
  204.     if(*lum++>128)
  205.       data |= bit;
  206.  
  207.     SHIFT_SEED_BIT(bit);
  208.     if(bit == 0) {
  209.       *out ++ = data;
  210.       bit = SEED_BIT;
  211.       data = 0;
  212.     }
  213.   }
  214. }
  215.